import type { RouteComponent, Router, RouteRecordRaw, RouterHistory } from 'vue-router'
import { close, start } from '@/utils/nprogress'
import { createRouter } from 'vue-router'

import remainingRouter from './modules/remaining'
import {
  ascending,
  buildHierarchyTree,
  filterTree,
  formatFlatteningRoutes,
  formatTwoStageRoutes,
  getHistoryMode,
  initRouter,
} from './utils'

/**
 * 自动导入全部静态路由
 */
const modules: Record<string, any> = import.meta.glob(
  ['./modules/**/*.ts', '!./modules/**/remaining.ts'],
  {
    eager: true,
  },
)

/** 原始静态路由（未做任何处理） */
const routes: RouteRecordRaw[] = []

Object.keys(modules).forEach((key) => {
  routes.push(modules[key].default)
})

/** 导出处理后的静态路由（三级及以上的路由全部拍成二级） */
export const constantRoutes: Array<RouteRecordRaw> = formatTwoStageRoutes(
  formatFlatteningRoutes(buildHierarchyTree(ascending(routes.flat(Infinity)))),
)

/** 用于渲染菜单，保持原始层级 */
export const constantMenus: RouteComponent[] = filterTree(
  ascending(routes.flat(Infinity)).concat(...remainingRouter),
)

/** 不参与菜单的路由 */
export const remainingPaths = Object.keys([]).map((v) => {
  return remainingRouter[Number(v)].path
})

const router = createRouter({
  history: getHistoryMode(import.meta.env.VITE_ROUTER_HISTORY) as RouterHistory,
  routes: constantRoutes.concat(...(remainingRouter)),
  strict: true,
  scrollBehavior(to, from, savedPosition) {
    // 默认滚动到顶部
    return new Promise((resolve) => {
      if (savedPosition) {
        return savedPosition
      }
      else {
        if (from.meta.saveSrollTop) {
          const top: number = document.documentElement.scrollTop || document.body.scrollTop
          resolve({ left: 0, top })
        }
      }
    })
  },
})

/** 重置路由 */
export function resetRouter() {
  router.getRoutes().forEach((route) => {
    const { name, meta } = route
    if (name && router.hasRoute(name) && meta?.backstage) {
      router.removeRoute(name)
      router.options.routes = formatTwoStageRoutes(
        formatFlatteningRoutes(buildHierarchyTree(ascending(routes.flat(Infinity)))),
      )
    }
  })
}

/** 路由白名单 */
const whiteList = ['/login', '/404', '/oauth/redirect']

router.beforeEach(async (to, _from, next) => {
  start()
  if (to.meta?.title) {
    setTitle(to.meta?.title as string)
  }
  if (useUserStoreHook().accessToken) {
    // 刷新（正常来说不会进入这个判断，因为在main.ts中已经初始化路由）
    if (useMenuStoreHook().menus.length === 0 && to.path !== '/login') {
      initRouter().then((router: Router) => {
        router.push({
          path: to.path,
          query: to.query,
          hash: to.hash,
        })
      })
    }
  }
  else {
    if (to.path !== '/login') {
      if (whiteList.includes(to.path)) {
        next()
      }
      else {
        useUserStoreHook().logout()
      }
    }
  }
  next()
})

router.afterEach(() => {
  close()
})

/**
 * 设置浏览器标题
 * @param title 标题
 */
function setTitle(title: string) {
  document.title = `${import.meta.env.VITE_APP_NAME}-${title}`
}

export default router
